/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package videorent;

import java.io.*;
import java.util.*;
/**
 *
 * @author Gimbet
 */
public class VideoRent{

    private static int proxCliente;
    private static ArrayList<Articulo> enStock;
    private static ArrayList<Accion> accEmpleados; 
    private static ArrayList<ClienteAsociado> clientes;
    private String[] facturas;
    private static ArrayList<Articulo> rentados;
    private Calendar fechaActual;
    

    public VideoRent() {    
        
        
        this.accEmpleados = new ArrayList<Accion>();
        this.enStock = new ArrayList<Articulo>();
        this.clientes = new ArrayList<ClienteAsociado>();
        this.fechaActual = Calendar.getInstance();
        this.rentados = new ArrayList<Articulo>();
        
   }
    
             
    public static void main (String[] args){
 
           VideoRent vr = new VideoRent();
           if (args.length == 3 ) {
                vr.leerArticulosExistentesAntes(args[0]);
                vr.leerClientesAsociadosAntes(args[1]);
                vr.leerAccionesClientes(args[2]);
                vr.rentados.toString();
                vr.clientes.toString();
           }else{
               System.err.println("Sintaxis: prog <articulosExistentesAntes > <clientesAsociadosAntes> <accionesClientes>}");
               System.exit(-1);
           }
      
    }
    
    public void leerArticulosExistentesAntes(String args){ 
        BufferedReader in;
        try{

           in = new BufferedReader(new FileReader(args));
				
           try{
              // leer archivo articulosExistentesAntes
              String linea = in.readLine();
              Articulo art;
              int numart = Integer.parseInt(linea);
              for ( int k = 0 ; k != numart; k++){
                  linea = in.readLine();
                  this.enStock.add(crearArticulo(linea));
                  art= crearArticulo(articulo);
                  enStock.add(art);
              }
             			
             } catch (Exception ioe){
                 System.err.println("Error Abriendo el archivo: articulosExistentesAntes");
             }
           } catch (FileNotFoundException fnfe){
                System.err.println("Error Abriendo el archivo: articulosExistentesAntes");
           }
    }
    
    private Articulo crearArticulo(String linea){
        String[] articulo = linea.split(" & ");
        String codArt = articulo[0];
        char aux = codArt.charAt(0);
                          
        if (aux == 'P'){
            Articulo p = new Articulo(codArt);                                  
            if (articulo.length == 10){
                p =  new Pelicula(codArt,articulo[2],Integer.parseInt(articulo[3]),
                              articulo[4],Pelicula.Formato.valueOf(articulo[5]),articulo[6],articulo[7],articulo[8],articulo[9]);
            } else if (articulo.length == 9){
                p = new Pelicula(codArt,articulo[2],Integer.parseInt(articulo[3]),
                             articulo[4],Pelicula.Formato.valueOf(articulo[5]),articulo[6],articulo[7],articulo[8]);
            }
            p.setNumDiasR(3);
            p.setPrecioR(10);
            p.setPrecioV(90);
            p.setCostAd(5);
            p.setCantArt(Integer.parseInt(articulo[1]));
            return p;
        } else if (aux == 'S'){
                Articulo ts = new TempSeries(codArt,articulo[2],Integer.parseInt(articulo[3]),
                             Integer.parseInt(articulo[4]),articulo[5],articulo[6],
                             Integer.parseInt(articulo[7]));
                ts.setNumDiasR(3);
                ts.setPrecioR(10);
                ts.setPrecioV(100);
                ts.setCostAd(5);
                ts.setCantArt(Integer.parseInt(articulo[1]));
                return ts;
                
        } else if (aux == 'R'){
                Articulo jr = new JuegoRecreativo(codArt,articulo[2],articulo[3],articulo[4],
                              articulo[5],Integer.parseInt(articulo[6]));
                jr.setNumDiasR(2);
                jr.setPrecioR(12);
                jr.setPrecioV(250);
                jr.setCostAd(10);
                jr.setCantArt(Integer.parseInt(articulo[1]));
                return jr;
        } else if (aux == 'E'){
               Articulo je = new JuegoEduc(codArt,articulo[2],articulo[3],articulo[4],
                              Integer.parseInt(articulo[5]));
                je.setNumDiasR(5);
                je.setPrecioR(7);
                je.setPrecioV(50);
                je.setCostAd(1);
                je.setCantArt(Integer.parseInt(articulo[1]));
                return je;
        }
        return null;
    }
    
    public void leerClientesAsociadosAntes(String args){
        BufferedReader in;
        try{
            in = new BufferedReader(new FileReader(args));
				
            try {
                 // leer archivo clientesAsociadosAntes
                 String linea = in.readLine();
                 String[] num = linea.split(" ");
                 int numCli = Integer.parseInt(num[0]);
                 proxCliente = Integer.parseInt(num[1]);
                 ClienteAsociado cli;
                 for ( int k = 0 ; k != numCli ; k++){
                     linea = in.readLine();
                     String[] datosCli = linea.split(" & ");
                     this.clientes.add(registrarCliente(datosCli));
                 }
                  
                } catch (Exception ioe){
                    System.err.println("Error Abriendo el archivo: clientesAsociadosAntes");
                }
           } catch (FileNotFoundException fnfe){
               System.err.println("Error Abriendo el archivo: clientesAsociadosAntes");
           }
     }
    
    private ClienteAsociado registrarCliente(String[] datosCli){
        String codCli = datosCli[0];
        char membresia = codCli.charAt(0);
        String[] fecha = datosCli[10].split("/");
        int mes = Integer.parseInt(fecha[0]);
        int ano = Integer.parseInt(fecha[1]);
        Calendar fechaVen = Calendar.getInstance();
        fechaVen.set(01,mes,ano); 
        
        
        if (membresia == 'P'){
            ClienteAsociado cp = new ClientePremium(codCli,datosCli[1],Integer.parseInt(datosCli[2]),datosCli[3],
                           datosCli[4],Integer.parseInt(datosCli[5]),datosCli[6],Long.parseLong(datosCli[7]),
                           datosCli[8],Integer.parseInt(datosCli[9]),fechaVen);
            return cp;
            
        } else if (membresia == 'B'){
             ClienteAsociado cb = new ClienteBasico(codCli,datosCli[1],Integer.parseInt(datosCli[2]),datosCli[3],
                           datosCli[4],Integer.parseInt(datosCli[5]),datosCli[6],Long.parseLong(datosCli[7]),
                           datosCli[8],Integer.parseInt(datosCli[9]),fechaVen);
             return cb;
        }
        return null;
    }
    
    public void leerAccionesClientes(String args){
        BufferedReader in;
        try{
            in = new BufferedReader(new FileReader(args));
		
            try {
                 // leer archivo accionesClientes
                 String linea = in.readLine();
                 String[] numdya = linea.split(" ");
                 //System.out.println(linea);
                 int numdias = Integer.parseInt(numdya[0]);
                 int numacc = Integer.parseInt(numdya[1]);
                 linea = in.readLine();
                 //System.out.println(linea);
                 String[] fecha = linea.split("/");
                 int dia = Integer.parseInt(fecha[0]);
                 int mes = Integer.parseInt(fecha[1]);
                 int ano = Integer.parseInt(fecha[2]);
                                		
                 for (int k = 0; k!= numdias ; k++){
                    linea = in.readLine();
                    //System.out.println(linea);
                    
                    while (!(linea.equals("#"))){
                        String[] accCli = linea.split(" & ");
                        crearAccion(accCli[0],accCli);
                        //System.out.println("listo");
                        linea = in.readLine();
                        //System.out.println(accCli[0]);
                    }
                    //System.out.println(linea);
                    this.fechaActual.add(Calendar.DATE,1);
                   // System.out.println(linea);
                    chequeoMatutino(this.fechaActual);
                   // System.out.println(linea);
                    
                 }              
                 						 
            } catch (Exception ioe){
		System.err.println("Error Abriendo el archivo: accionesClientes");
            }
        } catch (FileNotFoundException fnfe){
            System.err.println("Error Abriendo el archivo: accionesClientes");
        }
		
    }
   
    public void crearAccion(String cod, String[] linea){      
      ClienteAsociado claux;      
      if ("a".equals(cod)){  //Accion asociarse -> Registrar un asociado
          String[] fecha = linea[9].split("/");
          int mesVenc = Integer.parseInt(fecha[0]);
          int anoVenc = Integer.parseInt(fecha[1]);
          Calendar fechaVen = Calendar.getInstance();
          fechaVen.set(Calendar.MONTH,mesVenc-1);
          fechaVen.set(Calendar.YEAR,anoVenc-1);
          fechaVen.set(Calendar.DATE,0);
          ClienteAsociado cl;
          claux = ClienteAsociado.buscarAsociado("B"+String.valueOf(proxCliente),this.clientes);
	  cl = ClienteAsociado.buscarAsociado("P"+String.valueOf(proxCliente),this.clientes);
          if (claux!=null){
              Accion acc = new Accion("i",claux,5,fechaActual);
              this.accEmpleados.add(acc);
          } else if (cl!=null) {
              Accion acc = new Accion("i",cl,5,fechaActual);
              this.accEmpleados.add(acc);
          } else {
              fechaVen.add(Calendar.DATE,-35);
              if (this.fechaActual.before(fechaVen)){
                  if ("basica".equals(linea[10])){
                      cl = new ClienteBasico("B"+String.valueOf(proxCliente),
                      "activo",Integer.parseInt(linea[1]),linea[2],linea[3],Integer.parseInt(linea[4]),
                      linea[5],Long.parseLong(linea[6]),linea[7],Integer.parseInt(linea[8]),fechaVen);
                  } else {
                      cl = new ClientePremium("P"+String.valueOf(proxCliente),
                      "activo",Integer.parseInt(linea[1]),linea[2],linea[3],Integer.parseInt(linea[4]),
                      linea[5],Long.parseLong(linea[6]),linea[7],Integer.parseInt(linea[8]),fechaVen);  
                  }
             } else {
                  if ("basica".equals(linea[10])){
                      cl = new ClienteBasico("B"+String.valueOf(proxCliente),
                      "suspendido",Integer.parseInt(linea[1]),linea[2],linea[3],Integer.parseInt(linea[4]),
                      linea[5],Long.parseLong(linea[6]),linea[7],Integer.parseInt(linea[8]),fechaVen);
                  } else {
                      cl = new ClientePremium("P"+String.valueOf(proxCliente),
                      "suspendido",Integer.parseInt(linea[1]),linea[2],linea[3],Integer.parseInt(linea[4]),
                      linea[5],Long.parseLong(linea[6]),linea[7],Integer.parseInt(linea[8]),fechaVen);              
                  }
              }
          proxCliente++;
          Accion acc = new Accion("r",cl,fechaActual);
          this.accEmpleados.add(acc);
          this.clientes.add(cl);
          }

      } else if("t".equals(cod)){
	  
          ClienteAsociado cl1 = ClienteAsociado.buscarAsociado(linea[1],this.clientes);
          if (cl1!=null){
              cl1.setNumTC(Long.parseLong(linea[2]));
              cl1.setBancoTC(linea[3]);
              cl1.setCodSegTC(Integer.parseInt(linea[4]));
              String[] fecha = linea[5].split("/");
              Calendar fechaVen = Calendar.getInstance();
              fechaVen.set(Calendar.MONTH,Integer.parseInt(fecha[0])-1);
              fechaVen.set(Calendar.YEAR,Integer.parseInt(fecha[1])-1);
              fechaVen.set(Calendar.DATE,0);
              cl1.setFechaVencTC(fechaVen); 
              cl1.setEstado("activo");
              Accion acc1 = new Accion("t",cl1);
              accEmpleados.add(acc1);
             
	  } else {
              Accion acc1 = new Accion("i",cl1,0,this.fechaActual);
              this.accEmpleados.add(acc1);
          }
      } 
	
      else if(("c".equals(cod)) || ("r".equals(cod))){ //No hay accion asociada
          // verificar si el cliente es valido
          ClienteAsociado cl = ClienteAsociado.buscarAsociado(linea[1],this.clientes);
          if (cl==null){
              Accion acc = new Accion("i",cl,0,fechaActual);
              this.accEmpleados.add(acc);
          } else {
              // verificar si el cliente esta suspendido
              String estado = cl.getEstado();
             if (estado.equals("suspendido")){
                  Accion acc = new Accion("i",cl,6);
                  this.accEmpleados.add(acc);
             } else {
                  // verificar existencia articulo
                 Articulo a = Articulo.buscarArticulo(linea[2],this.enStock);
                 if (a==null){
                      Accion acc = new Accion("i",cl,1,fechaActual);
                      this.accEmpleados.add(acc);
                 } else {       
                      Caja caja = new Caja(cl);
                      if ("c".equals(cod)){
                          a.setEstado("En compra");
                      } else { 
                          a.setEstado("En renta");
                     }
                      caja.agregarArticuloEnCaja(a);                  
                      a.setCantArt((a.getCantArt())-1);
                  }
              }
          }
      
          
      } else if ("p".equals(cod)) {
        ClienteAsociado cliente = ClienteAsociado.buscarAsociado(linea[1],this.clientes);
        Caja caja = new Caja(cliente);
          //Verifico en caja cuantos articulos hay en renta
          ArrayList<Articulo> enCaja = caja.getArticulosEnCaja();
          int contRenta = 0;
          int montoTotal = 0;
          if (enCaja.isEmpty()) {
             if (cliente.getDeuda()== 0){
                  Accion acc = new Accion("i",cliente,7,this.fechaActual);
                  this.accEmpleados.add(acc);
             } else {
                  if (Integer.parseInt(linea[2])<cliente.getDeuda()){
                       Accion acc = new Accion("i",cliente,3,this.fechaActual);
                       this.accEmpleados.add(acc);
                  } else if (Integer.parseInt(linea[2]) > montoTotal){
                       Accion acc = new Accion("i",cliente,4,this.fechaActual);
                       this.accEmpleados.add(acc);
                  } else {
                      cliente.setDeuda(0);
                  }
              }
          } else {
         
          for(int k = 0; k<enCaja.size(); k++){
              Articulo art= enCaja.get(k);
              if (art.getEstado().equals(("En renta"))){
                  contRenta++;
                  montoTotal = montoTotal + art.getPrecioR();
              } else if (art.getEstado().equals("En compra")){
                  montoTotal = montoTotal + art.getPrecioV();
              }
          } 
          if ( (contRenta > cliente.getCantI()) || (contRenta > cliente.getCantAV())){
              Accion acc = new Accion("i",cliente,2,this.fechaActual);
              this.accEmpleados.add(acc);
          } else {
              //Verificar monto
              if (Integer.parseInt(linea[2]) < montoTotal){
                  Accion acc = new Accion("i",cliente,3,this.fechaActual);
                  this.accEmpleados.add(acc);
              } else if (Integer.parseInt(linea[2]) > montoTotal){
                  Accion acc = new Accion("i",cliente,4,this.fechaActual);
                  this.accEmpleados.add(acc);
              } else {
                  //Cambiar el estado de los articulos rentados y eliminar los articulos comprados
                  for(int i = 0; i<enCaja.size();i++){
                      Articulo art = enCaja.get(i);
                      if (art.getEstado().equals("En renta")){ //revisar estado en renta
                          if (art.getCantArt()==1){
                              art.setEstado("Rentado");
                          }
						  else if (art.getCantArt()>1){
						      art.setEstado("Disponible");
						  }
                          cliente.agregarArticuloRentado(art); // no esta guardando el art en articulosrentados
                          Calendar fecha = Calendar.getInstance();
                          art.setDiaRenta(fecha);
						  Calendar fecha2 = Calendar.getInstance();
                          fecha2.add(Calendar.DATE,art.getNumDiasR());
                          art.setDiaRetorno(fecha2);
                          Calendar fecha1 = Calendar.getInstance();
                          fecha1.add(Calendar.DATE,30);
                          art.setDiaPerdida(fecha1);
                          this.rentados.add(art);
                          caja.setMontoTotal(montoTotal);
                          caja.generarFactura();
                          caja.eliminarArticuloEnCaja(art);	 
						  }
			} else if (art.getEstado().equals("En compra")){
                            caja.setMontoTotal(montoTotal);	
                            caja.generarFactura();
                            caja.eliminarArticuloEnCaja(art);
                            this.enStock.remove(art);
                        }
                  }
              }
          }
          }
       
      } else if ("b".equals(cod)){ //Cliente abandona la tienda
          ClienteAsociado cl = ClienteAsociado.buscarAsociado(linea[1],this.clientes);
          Caja caja = new Caja(cl);
          if (cl==null){
              Accion acc = new Accion("i",cl,0,fechaActual);
              this.accEmpleados.add(acc);
          } else {
              if (caja.getCliente().equals(cl)){
                  ArrayList<Articulo> articulos = caja.getArticulosEnCaja();
                  for(int i = 0; i<articulos.size(); i++){
                      articulos.get(i).setEstado("Disponible");                     
                      articulos.get(i).setCantArt(articulos.get(i).getCantArt()+1);
                  }
             } else {
                Accion acc = new Accion("i",cl,7);   
                this.accEmpleados.add(acc);
              }
          }
               
      } else if (("d").equals(cod)){
         ClienteAsociado cl = ClienteAsociado.buscarAsociado(linea[1],this.clientes);
         if (cl==null){
              Accion acc = new Accion("i",cl,0,this.fechaActual);
              this.accEmpleados.add(acc);
          } else { 
              Articulo art = Articulo.buscarArticulo(linea[2],this.enStock);
              if (art == null){
              Accion acc = new Accion("i",cl,7,this.fechaActual);
              this.accEmpleados.add(acc);
              }else {
              art.setCantArt(art.getCantArt()+1);
              art.setEstado("Disponible");
          }
         }
         
		} else if (("e").equals(cod)){ //Solicitar buscar un articulo
         ClienteAsociado cl = ClienteAsociado.buscarAsociado(linea[0],this.clientes);
          if (cl==null){
            Accion acc = new Accion("i",cl,0,this.fechaActual);
            this.accEmpleados.add(acc);
            return null;
          }
          if (cl instanceof ClienteBasico){
             Accion acc = new Accion("i",cl,2,this.fechaActual);
             this.accEmpleados.add(acc);
             return null;      
          }
         Articulo art = Articulo.buscarArticulo(linea[1], enStock);
            if (art == null){
                    Accion acc = new Accion("i",cl,7,this.fechaActual);
                    this.accEmpleados.add(acc);
                    return null;    
            }
          Accion acc = new Accion("b",cl,art.getCodArt(),this.fechaActual);
          art.setCantArt(art.getCantArt()+1);
          art.setEstado("Disponible");
          this.accEmpleados.add(acc);
        }

     
      
    }
       
	   private void chequeoMatutino(Calendar fechaActual){
		
		for(int k =0; k<rentados.size(); k++){
          Articulo r = rentados.get(k);
          ClienteAsociado claux = r.getCliente();
          if (r.getDiaPerdida().equals(fechaActual)){      
                Accion acc = new Accion("p",claux,r.getCodArt(),fechaActual);
                accEmpleados.add(acc);
                claux.eliminarArticuloRentado(r);
                enStock.remove(r);
                this.rentados.remove(r);
				//GENERAR FACTURA
          } else if(r.getDiaRetorno().equals(fechaActual)){
              if (claux instanceof ClientePremium){
                Accion acc = new Accion("l",claux,this.fechaActual);
                this.accEmpleados.add(acc);
              }
          } else if (r.getDiaRetorno().before(this.fechaActual)){ // Chequeo de cobro de multa de rentados
                ClienteAsociado cliente = r.getCliente();   
                int deuda = cliente.getDeuda();
                cliente.setDeuda(deuda+r.getCostAd());
                  }
	    }
	   
	    //Chequear si el cliente puede estar suspendido por fecha de vencimiento TC
	   
		for (int i=0; i<this.clientes.size(); i++){
			ClienteAsociado cl = this.clientes.get(i);
			Calendar fechaVen = cl.getFechaVencTC();
                        fechaVen.add(Calendar.DATE,-35);
                        if (fechaActual.equals(fechaVen)){
                                cl.setEstado("Suspendido");
                                
                        }
                }
        
    }
       
	
	private void imprimirAccionesEmpleados(){
	 
	 try{
	 try { 
	    PrintWriter escribir = new PrintWriter(
                             new BufferedWriter(new FileWriter("accionesEmpleados.txt")));
		Calendar fechaAux = Calendar.getInstance();
		fechaAux = fechaActual;
		for (int i = accEmpleados.size()-1; i>-1;i--){
			Accion accion = accEmpleados.get(i);
			System.out.println("accion"+accion.toString()+"\n"+accion.getFechaAccion().get(Calendar.DAY_OF_MONTH));
			if (accion.getFechaAccion().before(fechaAux)){
			  escribir.println("#");
			  fechaAux = accion.getFechaAccion();
			}
			escribir.println(accion.toString());	
		}
		escribir.close();
	} catch (EOFException e) { 
	    System.out.println("Final de Stream");
	}
	} catch (IOException e){
		System.out.println("error");
	}
	
	}
	
	private void imprimirArticulosDespues(){
	 
	 try{
	 try { 
	    PrintWriter escribir = new PrintWriter(
                             new BufferedWriter(new FileWriter("articulosExistentesDespues.txt")));
		escribir.println(enStock.size());
		for(int i = 0; i<enStock.size();i++){
		  escribir.println(enStock.get(i).toString());
		}
		escribir.close();
	} catch (EOFException e) { 
	    System.out.println("Final de Stream");
	}
	} catch (IOException e){
		System.out.println("error");
	}
	
	}
	
	private static void imprimirArticulosPrestados(){
	 try{
	 try { 
	    PrintWriter escribir = new PrintWriter(
                             new BufferedWriter(new FileWriter("articulosRentados.txt")));
		escribir.println(rentados.size());
		for(int i = 0; i<rentados.size();i++){
		  escribir.println(rentados.get(i).toString());
		}
		escribir.close();
	} catch (EOFException e) { 
	    System.out.println("Final de Stream");
	}
	} catch (IOException e){
		System.out.println("error");
	}
	
	}
	
	private static void imprimirClientesAsociadosDespues(){
	try{
	 try { 
	    PrintWriter escribir = new PrintWriter(
                             new BufferedWriter(new FileWriter("clientesAsociadosDespues.txt")));
		escribir.println(clientes.size()+ " "+proxCliente);
		for(int i = 0; i<clientes.size();i++){
		  escribir.println(clientes.get(i).toString());
		}
		escribir.close();
	} catch (EOFException e) { 
	    System.out.println("Final de Stream");
	}
	} catch (IOException e){
		System.out.println("error");
	}
	
	}
	
}

   
